--  local KleeU = require "packages/klee_xy_I/utility/k_utility"

---@class KleeU
local KleeU = {}

-- 玩家选择是否（邪道，但能用）
---@param to ServerPlayer @ 目标
---@param prompt? string @ 提示语
---@param skill_name? string @技能名
---@return boolean @是否
function KleeU.askYesOrNo(to, prompt ,skill_name)
  local aprompt = prompt or "请选择"
  local askill_name = skill_name or ""
  local _,_,choose = to.room:askToChooseCardsAndPlayers(to,{
    min_card_num = 0,
    max_card_num = 0,
    min_num = 0,
    max_num = 0,
    targets = {},
    prompt = aprompt,
    skill_name = askill_name,
  })
  return choose
end

-- 自由变更势力
---@param to ServerPlayer @ 目标
---@param skill_name string @ 技能名
---@param same? boolean @ 原地tp
---@param more? string[] @ 额外势力
---@param less? string[] @ 排除势力
function KleeU.asktoChangeKingdom(to, skill_name, same, more, less)
  local list = {"wei", "shu", "wu", "qun", "jin"}
  local amore = more or {}
  local aless = less or {}
  local asame = same or false
  if not asame then
    table.insertIfNeed(aless,to.kingdom)
  end
  for _, kingdom in ipairs(amore) do
    table.insertIfNeed(list, kingdom)
  end
  for _, p in ipairs(to.room:getAllPlayers()) do
    table.insertIfNeed(list, p.kingdom)
  end
  for _, kingdom in ipairs(aless) do
    table.removeOne(list, kingdom)
  end

  local kingdom = to.room:askToChoice(to, {
    choices = list,
    skill_name = skill_name,
    prompt = "AskForKingdom",
    cancelable = false,
  })
  if kingdom == to.kingdom then return end
  to.room:changeKingdom(to, kingdom, true)
end

--- 获取势力角色数列表，注意键unknown的值为nil
---@param room AbstractRoom @ 房间
---@param include_dead? boolean @ 包括死人
---@return table<string, number> @ 势力与角色数映射表
function KleeU.getKingdomPlayersNum(room, include_dead)
  local kingdomMapper = {}
  for _, p in ipairs(include_dead and room.players or room.alive_players) do
    local kingdom = p.kingdom
    if kingdom ~= "unknown" then
      kingdomMapper[kingdom] = (kingdomMapper[kingdom] or 0) + 1
    end
  end
  return kingdomMapper
end

--- 获取势力角色数列表，注意键unknown的值为nil
---@param room AbstractRoom @ 房间
---@param player? Player @ 角色，与此角色相同的势力，填写则覆盖``kingdom``
---@param kingdom? string @ 势力，与``player``参数至少要填写一个
---@param include_dead? boolean @ 包括死人
---@return integer
function KleeU.getSameKingdomPlayersNum(room, player, kingdom, include_dead)
  assert(player or kingdom, "must provide player or kingdom")
  if player then kingdom = player.kingdom end
  if kingdom == "unknown" then return 0 end
  local ret = 0
  for _, p in ipairs(include_dead and room.players or room.alive_players) do
    if p.kingdom == kingdom then
      ret = ret + 1
    end
  end
  return ret
end

--- 判断角色是否为大势力角色
---@param player Player
---@return boolean
function KleeU.isBigKingdomPlayer(player)
  if player.kingdom == "unknown" then return false end
  local room = Fk:currentRoom()

  local mapper = KleeU.getKingdomPlayersNum(room)
  local num = mapper[player.kingdom]
  if num < 2 then return false end
  for k, n in pairs(mapper) do
    if n > num then return false end
  end
  return true
end

--- 调整手牌至N
--- @param player ServerPlayer @ 角色
--- @param tar integer @ 目标数
--- @param skell_name? string @ 技能名
--- @return integer[] @ 摸或弃置的牌
function KleeU.adjustHandCards(player, tar,skell_name)
  local skel = skell_name or ""
  local cards = {}
  local n = player:getHandcardNum() - tar
  if n > 0 then
    cards = player.room:askToDiscard(player, {
      min_num = n,
      max_num = n,
      include_equip = false,
      skill_name = skel,
      cancelable = false,
    })
  else
    n = tar - player:getHandcardNum()
    if n > 0 then
      cards = player:drawCards(n, skel)
    end
  end
  return cards
end

---从a算到b的路径
---@param a ServerPlayer
---@param b ServerPlayer
---@return Player[],Player[]
function KleeU.roadTo(a,b)
  local room = a.room
  local lista = {}
  local listb = {}
  local temp = a:getNextAlive()
  while temp ~= b and temp ~= a do
    table.insertIfNeed(lista,temp)
    temp = temp:getNextAlive()
  end
  temp = b:getNextAlive()
  while temp ~= b and temp ~= a do
    table.insertIfNeed(listb,temp)
    temp = temp:getNextAlive()
  end
  return lista,listb
end

---玩家有否在短路径中并返回路径
---@param player ServerPlayer
---@param a ServerPlayer
---@param b ServerPlayer
---@return Player[]
function KleeU.PlayerInRoad(player,a,b)
  local lista,listb = KleeU.roadTo(a,b)
  if #lista <= #listb then
    if table.contains(lista,player) then
      return lista
    end
  end
  if #listb <= #lista then
    if table.contains(listb,player) then
      return listb
    end
  end
  return {}
end

return KleeU